package org.xmap.ui;

import java.util.Enumeration;
import java.util.Vector;

import javax.microedition.lcdui.Graphics;

import org.xmap.app.Env;
import org.xmap.ui.base.Event;
import org.xmap.ui.base.Rect;
import org.xmap.ui.base.Window;
import org.xmap.ui.control.CircleGuage;
import org.xmap.ui.control.Guage;
import org.xmap.ui.control.Label;
import org.xmap.ui.control.Menu;
import org.xmap.ui.control.Menubar;
import org.xmap.ui.control.MessageBox;
import org.xmap.ui.listener.MenuListener;

/**
 * <p>视图类，开发者从该类派生来显示界面，通过添加菜单和窗口控件，丰富界面的元素，通过实现菜单或按键等回调函数来处理事件。</p>
 * @author Zealot
 * @version 1.0
 */
public abstract class View implements MenuListener {

    /**
     * 无动画切换效果常量。
     */
    public static final int ANIMATION_NONE = 0;
    /**
     * 从左到右的动画切换效果常量。
     */
    public static final int ANIMATION_LEFT_TO_RIGHT = 1;
    /**
     * 从右到左的动画切换效果常量。
     */
    public static final int ANIMATION_RIGHT_TO_LEFT = -1;
    /**
     * 当前视图的区域。
     */
    protected Rect rect;
    /**
     * 上一个视图的引用，保存下来是为了能够快速返回。
     */
    protected View back;
    /**
     * 标题栏控件。
     */
    protected Label title;
    /**
     * 是否显示滚动条。
     */
    protected boolean showGuage;
    /**
     * 是否显示非模态滚动条。
     */
    protected boolean showModelessGuage;
    /**
     * 菜单控件。
     */
    protected Menubar menubar;
    /**
     * 消息框控件。
     */
    protected MessageBox msgBox;
    /**
     * 滚动条控件。
     */
    protected Guage g;
    /**
     * 非模态滚动控件。
     */
    protected CircleGuage cg;
    /**
     * 所有子控件。
     */
    protected Vector subControls;
    /**
     * 动画状态，0表示没有，1表示从左到右，-1表示从右到左。
     */
    protected byte animationState;
    /**
     * 动画横坐标偏移。
     */
    protected short animationXOffset;
    /**
     * 是否需要动态重置屏幕。
     */
    protected boolean enableReset;

    /**
     * 默认构造函数。
     */
    public View() {
        this(null);
    }

    /**
     * 指定返回视图的构造函数。
     * @param back View 返回的视图。
     */
    public View(View back) {
        this.rect = new Rect(0, 0, 0, 0);
        this.back = back;
        this.title = new Label(null, 0, 0, 0, 0);
        this.title.setShowRect(false);
        this.showGuage = false;
        this.menubar = new Menubar(this, this);
        this.animationState = 0;
        this.animationXOffset = 0;
        this.enableReset = true;
        this.reset(Env.instance.screenWidth, Env.instance.screenHeight); // 重置视图大小
        this.setAnimation(View.ANIMATION_NONE);
    }

    /**
     * 获得视图的区域。
     * @return Rect 视图区域。
     */
    public final Rect getRect() {
        return this.rect;
    }

    /**
     * 设置返回的视图。
     * @param v View 返回的视图。
     */
    public final void setBackView(View v) {
        this.back = v;
    }

    /**
     * 获得返回的视图。
     * @return View 返回的视图。
     */
    public final View getBackView() {
        return this.back;
    }

    /**
     * 设置标题的名字。
     * @param title String 标题名字。
     */
    public final void setTitleText(String title) {
        this.title.setText(title);
        ViewManager.instance.requestRepaint();
    }

    /**
     * 获得标题的名字。
     * @return String 标题名字。
     */
    public final String getTitleText() {
        return this.title.getText();
    }

    /**
     * 获得当前可用的区域，也就是除了标题栏和菜单栏以外的区域。
     * @return Rect 可用的区域。
     */
    public final Rect getClientRect() {
        if (Theme.instance.showTitle) {
            return new Rect(0, this.title.getRect().height, this.rect.width,
                            this.rect.height - this.title.getRect().height - this.menubar.getRect().height);
        } else {
            return new Rect(0, 0, this.rect.width, this.rect.height - this.menubar.getRect().height);
        }
    }

    /**
     * 获得当前视图的显示消息框状态。
     * @return boolean 是否显示消息框。
     */
    public boolean getShowMsgBox() {
        return this.menubar.getTemporary();
    }

    /**
     * 获得当前视图的显示进度条状态。
     * @return boolean 是否显示进度条。
     */
    public boolean getShowGuage() {
        return this.showGuage;
    }

    /**
     * 获得当前菜单是否弹出。
     * @return boolean 当前菜单是否弹出。
     */
    public boolean getMenuPop() {
        return this.menubar.getMenuPop();
    }

    /**
     * 添加指定名称的菜单到左侧菜单组。
     * @param command String 菜单名称。
     */
    public final void addLeftMenu(String command) {
        if (command != null) {
            this.menubar.addLeftMenu(command);
        }
    }

    /**
     * 添加指定名称的菜单和子菜单到左侧菜单组。
     * @param command String 菜单名称。
     * @param subCommand String[] 子菜单名称数组。
     */
    public final void addLeftMenu(String command, String[] subCommand) {
        if (command != null) {
            this.menubar.addLeftMenu(command, subCommand);
        }
    }

    /**
     * 直接设置左侧菜单组。
     * @param m Menu 菜单。
     */
    public final void setLeftMenu(Menu m) {
        if (m != null) {
            this.menubar.setLeftMenu(m);
        }
    }

    /**
     * 把指定名字的菜单改为新的名字。
     * @param from String 旧菜单名字。
     * @param to String 新菜单名字。
     */
    public final void changeLeftMenu(String from, String to) {
        if (from != null && to != null) {
            this.menubar.changeLeftMenu(from, to);
        }
    }

    /**
     * 移除指定名字的左侧菜单。
     * @param command String 菜单名字。
     * @return boolean 是否移除成功。
     */
    public final boolean removeLeftMenu(String command) {
        if (command != null) {
            return this.menubar.removeLeftMenu(command);
        } else {
            return false;
        }
    }

    /**
     * 移除所有的左侧菜单。
     */
    public final void removeAllLeftMenu() {
        this.menubar.removeAll();
    }

    /**
     * 设置右侧菜单的名字。
     * @param command String 菜单名字。
     */
    public final void setRightMenu(String command) {
        if (command != null) {
            this.menubar.setRightMenu(command);
        }
        this.requestRepaint();
    }

    /**
     * 弹出消息提示框。
     * @param left String 左侧菜单。
     * @param right String 右侧菜单。
     * @param msg String 提示信息。
     */
    public final void msgBox(String left, String right, String msg) {
        if (this.msgBox == null) {
            this.initMessageBox();
        }
        this.msgBox.setText(msg);
        this.msgBox.setText2(null);
        this.menubar.setTemporary(true, left, right);
        this.requestRepaint();
    }

    /**
     * 弹出消息提示框。
     * @param left String 左侧菜单。
     * @param right String 右侧菜单。
     * @param msg1 String 提示信息一。
     * @param msg2 String 提示信息二。
     */
    public final void msgBox(String left, String right, String msg1, String msg2) {
        if (this.msgBox == null) {
            this.initMessageBox();
        }
        this.msgBox.setText(msg1);
        this.msgBox.setText2(msg2);
        this.menubar.setTemporary(true, left, right);
        this.requestRepaint();
    }

    /**
     * 弹出消息提示框。
     * @param left String 左侧菜单。
     * @param right String 右侧菜单。
     * @param msg1 String 提示信息一。
     * @param msg1H String 高亮的提示信息一。
     * @param msg2 String 提示信息二。
     * @param msg2H String 高亮的提示信息二。
     */
    public final void msgBox(String left, String right, String msg1, String msg1H, String msg2, String msg2H) {
        if (this.msgBox == null) {
            this.initMessageBox();
        }
        this.msgBox.setText(msg1, msg1H);
        this.msgBox.setText2(msg2, msg2H);
        this.menubar.setTemporary(true, left, right);
        this.requestRepaint();
    }

    /**
     * 设置滚动条提示信息。
     * @param text1 String 提示信息一。
     * @param text1H String 高亮的提示信息一。
     * @param text2 String 提示信息二。
     * @param text2H String 高亮的提示信息二。
     */
    public final void setGuageText(String text1, String text1H, String text2, String text2H) {
        if (this.msgBox == null) {
            this.initMessageBox();
        }
        this.msgBox.setText(text1, text1H);
        this.msgBox.setText2(text2, text2H);
    }

    /**
     * 弹出滚动条，此时所有的子控件将不可用。
     */
    public final void showGuage() {
        this.showGuage = true;
        if (this.g == null) {
            this.initGuage();
        }
        if (this.subControls != null) {
            for (int i = 0; i < this.subControls.size(); i++) {
                Window w = (Window)this.subControls.elementAt(i);
                w.setEnablebackup();
                w.setEnable(false);
            }
        }
        this.menubar.setEnable(false);
        ViewManager.instance.requestRepaint();
    }

    /**
     * 隐藏滚动条，此时所有子控件的状态将恢复。
     */
    public final void hideGuage() {
        this.showGuage = false;
        if (this.subControls != null) {
            for (int i = 0; i < this.subControls.size(); i++) {
                Window w = (Window)this.subControls.elementAt(i);
                w.setEnable(w.getEnableBackup());
            }
        }
        this.menubar.setEnable(true);
        ViewManager.instance.requestRepaint();
    }

    /**
     * 锁定屏幕，所有按键和触笔事件均不可用。
     */
    public void lock() {
        if (this.subControls != null) {
            for (int i = 0; i < this.subControls.size(); i++) {
                Window w = (Window)this.subControls.elementAt(i);
                w.setEnablebackup();
                w.setEnable(false);
            }
        }
        this.menubar.setEnable(false);
        ViewManager.instance.requestRepaint();
    }

    /**
     * 解除屏幕锁定，恢复按键和触笔事件响应。
     */
    public void unlock() {
        if (this.subControls != null) {
            for (int i = 0; i < this.subControls.size(); i++) {
                Window w = (Window)this.subControls.elementAt(i);
//                w.setEnable(w.getEnableBackup());
                w.setEnable(true);
            }
        }
        this.menubar.setEnable(true);
        ViewManager.instance.requestRepaint();
    }

    /**
     * 设置是否启用左侧菜单。
     * @param enable boolean 是否启用左侧菜单。
     */
    public void setEnableLeftMenu(boolean enable) {
        this.menubar.setEnableLeftMenu(enable);
    }

    /**
     * 获得是否启用左侧菜单。
     * @return boolean 是否启用左侧菜单。
     */
    public boolean getEnableLeftMenu() {
        return this.menubar.getEnableLeftMenu();
    }

    public void setEnableReset(boolean enable) {
        this.enableReset = enable;
    }

    public boolean getEnableRest() {
        return this.enableReset;
    }

    /**
     * 显示非模态滚动条。
     */
    public final void showModelessGuage() {
        if (!showModelessGuage) {
            if (this.cg == null) {
                this.initCircleGuage();
            } else {
                this.cg.resetIndex();
            }
            this.showModelessGuage = true;
            this.requestRepaint();
        }
    }

    /**
     * 隐藏非模态滚动条。
     */
    public final void hideModelessGuage() {
        if (this.showModelessGuage) {
            this.showModelessGuage = false;
            this.requestRepaint();
        }
    }

    /**
     * 添加子窗口控件到当前视图。
     * @param w Window 新的窗口。
     */
    public final void addControls(Window w) {
        if (w != null) {
            if (this.subControls == null) {
                this.subControls = new Vector(8);
            }
            if (!this.subControls.contains(w)) {
                // 判断是否有控件具有焦点，如果有焦点，则新的控件失去焦点，否则得到焦点。
                boolean hasFocus = false;
                for (int i = 0; i < this.subControls.size(); i++) {
                    Window obj = (Window)this.subControls.elementAt(i);
                    if (obj.getFocus()) {
                        hasFocus = true;
                        break;
                    }
                }
                this.subControls.addElement(w);
                w.setOwner(this);
                w.sizeChanged(this.rect.width, this.rect.height);
                if (!hasFocus) { // 如果当前视图没有控件获得焦点，并且新控件可以聚焦，这把焦点放在新控件上。
                    if (w.getCanFocus()) {
                        w.setFocus(true);
                    }
                } else {
                    w.setFocus(false);
                }
                this.requestRepaint();
            }
        }
    }

    /**
     * 检测指定窗口控件是否已经包含在视图中。
     * @param w Window 指定窗口控件。
     * @return boolean 是否包含在视图中。
     */
    public final boolean containControl(Window w) {
        if (w != null && this.subControls != null) {
            return this.subControls.contains(w);
        }
        return false;
    }

    /**
     * 移除指定的窗口控件。
     * @param w Window 指定的窗口控件。
     */
    public final void removeControl(Window w) {
        if (w != null) {
            if (w.getFocus()) {
                this.requestLossFocus(w, true); // 请求转移焦点到上一个控件。
            }
            if (this.subControls != null) {
                this.subControls.removeElement(w);
            }
            w.setOwner(null);
        }
    }

    /**
     * 移除所有的控件。
     */
    public final void removeAllControl() {
        if (this.subControls != null) {
            Enumeration e = this.subControls.elements();
            while (e.hasMoreElements()) {
                Window w = (Window) e.nextElement();
                w.setOwner(null);
            }
            this.subControls.removeAllElements();
        }
    }

    /**
     * 设置动画的效果，有从左到右和从右到左。
     * @param type int 动画效果，1为从左到右，-1为从有到左。
     */
    public void setAnimation(int type) {
        switch (type) {
        case View.ANIMATION_LEFT_TO_RIGHT:
            this.animationState = View.ANIMATION_LEFT_TO_RIGHT;
            this.animationXOffset = (short) - this.getRect().width;
            break;
        case View.ANIMATION_RIGHT_TO_LEFT:
            this.animationState = View.ANIMATION_RIGHT_TO_LEFT;
            this.animationXOffset = (short)this.getRect().width;
            break;
        default:
            this.animationState = View.ANIMATION_NONE;
            this.animationXOffset = 0;
            break;
        }
    }

    public void requestRepaint() {
        if (ViewManager.instance.getCurView() == this) {
            ViewManager.instance.requestRepaint();
        }
    }

    /**
     * 初始绘制函数。
     * @param g Graphics 图形句柄。
     */
    final void baseDraw(Graphics g) {
        int color = g.getColor();
        g.setColor(Theme.instance.viewBackgroundColor);
        g.fillRect(0, 0, this.rect.width, this.rect.height);
        int y = 0;
        if (Theme.instance.showTitle) {
            if (this.title.getShow()) {
                y = this.title.getRect().height;
            }
        }
        g.translate(this.animationXOffset, y);
        if (this.subControls != null) {
            Enumeration e = this.subControls.elements();
            while (e.hasMoreElements()) {
                Window w = (Window) e.nextElement();
                UIUtil.draw(g, w);
            }
        }
        this.draw(g);
        g.translate( -this.animationXOffset, -y);

        if (Theme.instance.showTitle) {
            UIUtil.draw(g, this.title);
        }

        if (this.menubar.getTemporary()) {
            if (this.msgBox != null) {
                UIUtil.draw(g, this.msgBox);
            }
        }
        if (this.menubar.getShow()) {
            g.translate(0, this.menubar.getRect().leftUp.y);
            this.menubar.draw(g);
            g.translate(0, -this.menubar.getRect().leftUp.y);
            if (this.showModelessGuage && this.cg != null) {
                UIUtil.draw(g, this.cg);
            } else {
                if (Theme.instance.showTime) {
                    g.setColor(0xffffff);
                    UIUtil.draw(g, Env.instance.strTime, this.rect.width >> 1,
                                this.rect.height - (this.menubar.getRect().height >> 1), Graphics.HCENTER, Graphics.VCENTER);
                }
            }
        }
        if (this.showGuage) {
            if (this.msgBox != null) {
                UIUtil.draw(g, this.msgBox);
            }
            if (this.g != null) {
                UIUtil.draw(g, this.g);
            }
        }

        g.translate(0, y);
        this.topDraw(g);
        g.translate(0, -y);

        g.setColor(color);
    }

    /**
     * 初始按键处理函数。
     * @param flag boolean 是按下还是抬起。
     * @param keyCode int 按键代码。
     * @param gameAction int 动作代码。
     */
    final void baseKeyEvent(boolean flag, int keyCode, int gameAction) {
        if (!this.showGuage) {
            // 菜单优先接收按键, 然后是view, 然后是view的子控件
            boolean processed = UIUtil.keyEvent(flag, keyCode, gameAction, this.menubar);
            if (processed == false) {
                processed = UIUtil.keyEvent(flag, keyCode, gameAction, this.title);
            }
            if (processed == false && this.subControls != null) {
                for (int i = this.subControls.size() - 1; i >= 0; i--) {
                    Window w = (Window)this.subControls.elementAt(i);
                    processed = UIUtil.keyEvent(flag, keyCode, gameAction, w);
                    if (processed) {
                        break;
                    }
                }
            }
            if (processed == false) {
                processed = this.keyEvent(flag, keyCode, gameAction);
            }
        }
    }

    /**
     * 初始触笔事件处理函数。
     * @param ev Event 触笔事件。
     */
    final void basePointerEvent(Event ev) {
        if (!this.showGuage) {
            boolean processed = UIUtil.pointerEvent(ev, this.menubar);
            if (processed == false) {
                if (Theme.instance.showTitle) {
                    processed = UIUtil.pointerEvent(ev, this.title);
                }
            }
            if (Theme.instance.showTitle && this.title.getShow()) {
                ev.param2 -= this.title.getRect().height;
            }
            if (processed == false && this.subControls != null) {
                for (int i = this.subControls.size() - 1; i >= 0; i--) {
                    Window w = (Window)this.subControls.elementAt(i);
                    processed = UIUtil.pointerEvent(ev, w);
                    if (processed) {
                        break;
                    }
                }
            }
            if (processed == false) {
                processed = this.pointerEvent(ev);
            }
        }
    }

    /**
     * 初始时间触发函数。
     */
    final void baseUpdate() {
        if (this.rect.width != Env.instance.screenWidth || this.rect.height != Env.instance.screenHeight) { // 检测屏幕宽度和高度
            if (this.getEnableRest()) {
                this.reset(Env.instance.screenWidth, Env.instance.screenHeight);
            }
        }
        switch (this.animationState) {
        case View.ANIMATION_LEFT_TO_RIGHT:
            if (this.animationXOffset < -(Env.instance.screenWidth >> 1)) {
                this.animationXOffset += (Env.instance.screenWidth >> 3);
            } else if (this.animationXOffset < -(Env.instance.screenWidth >> 3)) {
                this.animationXOffset += (Env.instance.screenWidth >> 4);
            } else {
                this.animationXOffset += (Env.instance.screenWidth >> 5);
            }
            if (this.animationXOffset > 0) {
                this.animationXOffset = 0;
                this.animationState = 0;
            }
            ViewManager.instance.requestRepaint();
            break;
        case View.ANIMATION_RIGHT_TO_LEFT:
            this.animationXOffset--;
            if (this.animationXOffset > (Env.instance.screenWidth >> 1)) {
                this.animationXOffset -= (Env.instance.screenWidth >> 3);
            } else if (this.animationXOffset > (Env.instance.screenWidth >> 3)) {
                this.animationXOffset -= (Env.instance.screenWidth >> 4);
            } else {
                this.animationXOffset -= (Env.instance.screenWidth >> 5);
            }
            if (this.animationXOffset < 0) {
                this.animationXOffset = 0;
                this.animationState = 0;
            }
            ViewManager.instance.requestRepaint();
            break;
        }
        this.update();
//        this.title.update();
        if (this.subControls != null) {
            Enumeration e = this.subControls.elements();
            while (e.hasMoreElements()) {
                Window w = (Window) e.nextElement();
                w.update();
            }
        }
//        if (this.menubar != null) {
//            this.menubar.update();
//        }
//        if (this.msgBox != null) {
//            this.msgBox.update();
//        }
        if (this.g != null) {
            this.g.update();
            if (this.showGuage) {
                ViewManager.instance.requestRepaint();
            }
        }
        if (this.showModelessGuage && this.cg != null) {
            if (this.cg.getColor() != Theme.instance.modelessGuageColor) {
                this.cg.setColor(Theme.instance.modelessGuageColor);
            }
            this.cg.update();
        }
    }

    /**
     * 指定的控件请求获得焦点。
     * @param w Window 指定的控件。
     * @return boolean 返回是否获得焦点。
     */
    public boolean requestGetFocus(Window w) {
        if (this.subControls != null) {
            if (this.subControls.contains(w) && w.getCanFocus()) {
                for (int i = 0; i < this.subControls.size(); i++) {
                    Window window = (Window)this.subControls.elementAt(i);
                    if (window != w) {
                        window.setFocus(false);
                    }
                }
                w.setFocus(true);
                return true;
            }
        }
        return false;
    }

    /**
     * 指定的控件请求失去焦点。
     * @param w Window 指定的控件。
     * @param forward boolean 是否让前一个控件优先获得焦点。
     * @return boolean 返回指定控件否失去焦点，因为如果没有合适的控件接收焦点，那么焦点将得不到释放。
     */
    public boolean requestLossFocus(Window w, boolean forward) {
        if (this.subControls != null && this.subControls.contains(w)) {
            int index = this.subControls.indexOf(w);
            if (forward) {
                for (int i = index - 1; i >= 0; i--) {
                    Window obj = (Window)this.subControls.elementAt(i);
                    if (obj.getCanFocus()) {
                        obj.setFocus(true);
                        w.setFocus(false);
                        return true;
                    }
                }
                for (int i = this.subControls.size() - 1; i > index; i--) {
                    Window obj = (Window)this.subControls.elementAt(i);
                    if (obj.getCanFocus()) {
                        obj.setFocus(true);
                        w.setFocus(false);
                        return true;
                    }
                }
            } else {
                for (int i = index + 1; i < this.subControls.size(); i++) {
                    Window obj = (Window)this.subControls.elementAt(i);
                    if (obj.getCanFocus()) {
                        obj.setFocus(true);
                        w.setFocus(false);
                        return true;
                    }
                }
                for (int i = 0; i < index; i++) {
                    Window obj = (Window)this.subControls.elementAt(i);
                    if (obj.getCanFocus()) {
                        obj.setFocus(true);
                        w.setFocus(false);
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 菜单响应函数，通过覆盖该函数来接收菜单事件。
     * @param command String 菜单名字。
     * @param sender Window 消息源。
     */
    public void commandEvent(String command, Window sender) {
    }

    /**
     * 留给派生类使用的绘制函数，派生类重写这个函数来实现绘制。
     * @param g Graphics 图形句柄。
     */
    public void draw(Graphics g) {
    }

    /**
     * 留给派生类使用的最顶层的绘制函数，派生类重写这个函数来实现最顶层的绘制，该函数主要用于改写继承自View的对象，可以实现最顶层的绘制，而不会受窗口的先后顺序的影响。
     * @param g Graphics 图形句柄。
     */
    public void topDraw(Graphics g) {
    }

    /**
     * 按键事件处理函数，默认所有的按键事件都被处理。
     * @param flag boolean 是按下还是抬起。
     * @param keyCode int 按键代码。
     * @param gameAction int 动作代码。
     * @return boolean 是否处理该事件。
     */
    public boolean keyEvent(boolean flag, int keyCode, int gameAction) {
        return true;
    }

    /**
     * 触笔事件处理函数，默认所有的触笔事件都被处理。
     * @param ev Event 触笔事件。
     * @return boolean 是否处理该事件。
     */
    public boolean pointerEvent(Event ev) {
        return true;
    }

    /**
     * 通知该窗口，屏幕的宽度和高度已经改变，是屏幕的宽度和高度，而不是窗口的宽度和高度，该函数用于窗口根据屏幕大小修改自己的大小。
     * @param width int 新的屏幕宽度。
     * @param height int 新的屏幕高度。
     */
    public void sizeChanged(int width, int height) {
    }

    /**
     * 时间触发函数，当窗口需要自己的逻辑的时候，通过重写该函数来实现。
     */
    public void update() {
    }

    /**
     * 调整View的宽度和高度，当屏幕发生变化时（例如从竖屏变成横屏），将调用这个函数。
     * @param width int 新的宽度。
     * @param height int 新的高度。
     * @return boolean 是否调整过。
     */
    protected final boolean reset(int width, int height) {
//        ViewManager.instance.debugPrint(this.toString() + " reset:w:" + Env.instance.screenWidth + " h:" + Env.instance.screenHeight);
        if (width != this.rect.width || height != this.rect.height) {
            // 只有subControls中的控件的坐标才受title的影响，其余的不受影响
            this.rect.setRect(0, 0, width, height);
            if (this.title != null) {
                this.title.setRect(0, 0, width, Theme.instance.titleHeight);
            }
            if (this.menubar != null) {
                this.menubar.setRect(0, height - Theme.instance.menubarHeight, width, Theme.instance.menubarHeight);
            }
            int guageX = (width * (100 - Theme.instance.guageWidthPercent) / 100) >> 1;
            int guageY = height * Theme.instance.guageYPercent / 100;
            int guageWidth = width * Theme.instance.guageWidthPercent / 100;
            if (this.msgBox != null) {
                int msgBoxHeight = (Theme.instance.msgBoxRowHeight * 5) >> 1;
                this.msgBox.setRect(guageX, guageY - 1 - msgBoxHeight, guageWidth, msgBoxHeight);
            }
            if (this.g != null) {
                this.g.setRect(guageX, guageY, guageWidth, Theme.instance.guageHeight);
            }
            if (this.cg != null) {
                int mbh = Theme.instance.menubarHeight;
                this.cg.setRect((this.getRect().width - mbh) >> 1, this.getRect().height - mbh, mbh);
            }
            if (this.subControls != null) {
                for (int i = 0; i < this.subControls.size(); i++) {
                    ((Window)this.subControls.elementAt(i)).sizeChanged(width, height);
                }
            }
            this.sizeChanged(width, height); // 通知派生类窗口已经修改
            return true;
        }
        return false;
    }

    protected void initMessageBox() {
        this.msgBox = new MessageBox();
        int guageX = (this.getRect().width * (100 - Theme.instance.guageWidthPercent) / 100) >> 1;
        int guageY = this.getRect().height * Theme.instance.guageYPercent / 100;
        int guageWidth = this.getRect().width * Theme.instance.guageWidthPercent / 100;
        int msgBoxHeight = (Theme.instance.msgBoxRowHeight * 5) >> 1;
        this.msgBox.setRect(guageX, guageY - 1 - msgBoxHeight, guageWidth, msgBoxHeight);
    }

    protected void initGuage() {
        int guageX = (this.getRect().width * (100 - Theme.instance.guageWidthPercent) / 100) >> 1;
        int guageY = this.getRect().height * Theme.instance.guageYPercent / 100;
        int guageWidth = this.getRect().width * Theme.instance.guageWidthPercent / 100;
        this.g = new Guage(guageX, guageY, guageWidth, Theme.instance.guageHeight, Window.ORIENT_LEFT_UP);
    }

    protected void initCircleGuage() {
        int height = Theme.instance.menubarHeight;
        this.cg = new CircleGuage((this.getRect().width - height) >> 1, this.getRect().height - height, height, 3, Theme.instance.modelessGuageColor);
        this.cg.setAdjust(Theme.instance.modelessGuageAlphaAdjust);
    }
}
